import arcade

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

class GeometryObject:
    """自定义几何对象基类，封装绘制和检测功能"""
    def __init__(self, color):
        self.color = color
        
    def draw(self):
        """在子类中实现具体绘制逻辑"""
        pass
        
    def contains(self, x, y):
        """在子类中实现点包含检测"""
        return False

class MyRectangle(GeometryObject):
    """矩形对象"""
    def __init__(self, center_x, center_y, width, height, color):
        super().__init__(color)
        self.center_x = center_x
        self.center_y = center_y
        self.width = width
        self.height = height
        
    def draw(self):
        arcade.draw_rectangle_filled(
            self.center_x, self.center_y,
            self.width, self.height,
            self.color
        )
        
    def contains(self, x, y):
        """点是否在矩形内"""
        left = self.center_x - self.width/2
        right = self.center_x + self.width/2
        bottom = self.center_y - self.height/2
        top = self.center_y + self.height/2
        
        return left <= x <= right and bottom <= y <= top

class MyCircle(GeometryObject):
    """圆形对象"""
    def __init__(self, center_x, center_y, radius, color):
        super().__init__(color)
        self.center_x = center_x
        self.center_y = center_y
        self.radius = radius
        
    def draw(self):
        arcade.draw_circle_filled(
            self.center_x, self.center_y,
            self.radius,
            self.color
        )
        
    def contains(self, x, y):
        """点是否在圆内"""
        distance_sq = (x - self.center_x)**2 + (y - self.center_y)**2
        return distance_sq <= self.radius**2

class MyPolygon(GeometryObject):
    """多边形对象"""
    def __init__(self, points, color):
        super().__init__(color)
        self.points = points
        
    def draw(self):
        arcade.draw_polygon_filled(self.points, self.color)
        
    def contains(self, x, y):
        """使用光线投射算法判断点是否在多边形内"""
        # 经典算法实现
        n = len(self.points)
        inside = False
        p1x, p1y = self.points[0]
        
        for i in range(n + 1):
            p2x, p2y = self.points[i % n]
            
            # 检查点是否在边的"上方"或"下方"
            if y > min(p1y, p2y):
                if y <= max(p1y, p2y):
                    if x <= max(p1x, p2x):
                        # 计算边与水平射线的交点x坐标
                        if p1y != p2y:
                            x_intersect = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
                            
                        if p1x == p2x or x <= x_intersect:
                            inside = not inside
            
            p1x, p1y = p2x, p2y
            
        return inside

class MyGame(arcade.Window):
    def __init__(self):
        super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, "点包含检测 - Arcade 3.2.0")
        
        # 创建自定义几何对象
        self.shapes = [
            MyRectangle(100, 100, 50, 30, arcade.color.BLUE),
            MyCircle(200, 200, 40, arcade.color.RED),
            MyPolygon([(300, 300), (350, 350), (320, 370), (280, 340)], arcade.color.GREEN)
        ]
        
    def on_draw(self):
        self.clear()
        # 绘制所有形状
        for shape in self.shapes:
            shape.draw()
        
    def on_mouse_press(self, x: float, y: float, button: int, modifiers: int):
        # 检测所有形状
        hit = False
        for i, shape in enumerate(self.shapes):
            if shape.contains(x, y):
                shape_type = type(shape).__name__[2:]  # 去掉"My"前缀
                print(f"点 ({x}, {y}) 在{shape_type}内!")
                hit = True
                
        if not hit:
            print(f"点 ({x}, {y}) 没有命中任何图形")
            
if __name__ == "__main__":
    game = MyGame()
    arcade.run()